﻿using UnityEngine;
using TouchTable.Input;
using System.Collections.Generic;
using PointerType = TouchTable.Point.PointerType;
using vector2 = System.Numerics.Vector2;

namespace UnityTouchTable.Runtime
{
    /// <summary>
    /// Touch输入源
    /// </summary>
    internal class TouchInput : BaseInputSource
    {
        /// <summary>
        /// Touch点字典
        /// key:Unity内部TouchID
        /// value:自身系统PointerID
        /// </summary>
        private Dictionary<int, int> m_Touchs;

        /// <summary>
        /// 构造函数
        /// </summary>
        public TouchInput()
        {

        }

        #region Base Function
        /// <summary>
        /// 当初始化时
        /// </summary>
        public override void OnInit()
        {
            base.OnInit();

            this.m_Touchs = new Dictionary<int, int>(30);
        }

        /// <summary>
        /// 当轮训时
        /// </summary>
        public override void OnUpdate()
        {
            base.OnUpdate();

            if (UnityEngine.Input.touchCount <= 0)
                return;

            for (int i = 0; i < UnityEngine.Input.touchCount; i++)
            {
                Touch temp_Touch = UnityEngine.Input.GetTouch(i);
                switch (temp_Touch.phase)
                {
                    case TouchPhase.Began:
                        this.OnTouchPhaseBegan(temp_Touch);
                        break;
                    case TouchPhase.Moved:
                        this.OnTouchPhaseMoved(temp_Touch);
                        break;
                    case TouchPhase.Stationary:
                        this.OnTouchPhaseStationary(temp_Touch);
                        break;
                    case TouchPhase.Ended:
                        this.OnTouchPhaseEnded(temp_Touch);
                        break;
                    case TouchPhase.Canceled:
                        this.OnTouchPhaseCanceled(temp_Touch);
                        break;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// 当销毁时
        /// </summary>
        public override void OnBreak()
        {
            base.OnBreak();

            if (this.m_Touchs != null)
            {
                this.m_Touchs.Clear();
                this.m_Touchs = null;
            }
        }
        #endregion

        #region Function
        /// <summary>
        /// 当Touch相位为按下时
        /// </summary>
        private void OnTouchPhaseBegan(Touch touch)
        {
            //already exist
            if (this.m_Touchs.TryGetValue(touch.fingerId, out int pointerID))
            {
                //移除已存在的
                this.m_Touchs.Remove(touch.fingerId);
                this.RemovePointer(pointerID);

                //重新添加
                int temp_PointerID = this.AddPointer(new vector2(touch.position.x, touch.position.y), PointerType.TOUCH);
                //更新本地字典
                this.m_Touchs.Add(touch.fingerId, temp_PointerID);
            }
            else
            {
                int temp_PointerID = this.AddPointer(new vector2(touch.position.x, touch.position.y), PointerType.TOUCH);
                this.m_Touchs.Add(touch.fingerId, temp_PointerID);
            }
        }

        /// <summary>
        /// 当Touch相位为移动时
        /// </summary>
        private void OnTouchPhaseMoved(Touch touch)
        {
            if (this.m_Touchs.TryGetValue(touch.fingerId, out int pointerID))
                this.UpdatePointer(pointerID, new vector2(touch.position.x, touch.position.y));
            //no exist
            else
            {
                int temp_PointerID = this.AddPointer(new vector2(touch.position.x, touch.position.y), PointerType.TOUCH);
                this.m_Touchs.Add(touch.fingerId, temp_PointerID);
            }
        }

        /// <summary>
        /// 当Touch相位为固定不动时
        /// </summary>
        private void OnTouchPhaseStationary(Touch touch)
        {
            //already exist
            if (this.m_Touchs.TryGetValue(touch.fingerId, out int pointerID))
            {
                //不处理
            }
            else
            {
                int temp_PointerID = this.AddPointer(new vector2(touch.position.x, touch.position.y), PointerType.TOUCH);
                this.m_Touchs.Add(touch.fingerId, temp_PointerID);
            }
        }

        /// <summary>
        /// 当Touch相位为抬起时
        /// </summary>
        private void OnTouchPhaseEnded(Touch touch)
        {
            //already exist
            if (this.m_Touchs.TryGetValue(touch.fingerId, out int pointerID))
            {
                this.m_Touchs.Remove(touch.fingerId);
                this.RemovePointer(pointerID);
            }
            else
            {
                //添加
                int temp_PointerID = this.AddPointer(new vector2(touch.position.x, touch.position.y), PointerType.TOUCH);
                this.m_Touchs.Add(touch.fingerId, temp_PointerID);

                //移除
                this.m_Touchs.Remove(touch.fingerId);
                this.RemovePointer(temp_PointerID);
            }
        }

        /// <summary>
        /// 当Touch相位为系统取消追踪时
        /// </summary>
        private void OnTouchPhaseCanceled(Touch touch)
        {
            //already exist
            if (this.m_Touchs.TryGetValue(touch.fingerId, out int pointerID))
            {
                this.m_Touchs.Remove(touch.fingerId);
                this.RemovePointer(pointerID);
            }
            else
            {
                //添加
                int temp_PointerID = this.AddPointer(new vector2(touch.position.x, touch.position.y), PointerType.TOUCH);
                this.m_Touchs.Add(touch.fingerId, temp_PointerID);

                //移除
                this.m_Touchs.Remove(touch.fingerId);
                this.RemovePointer(temp_PointerID);
            }
        }
        #endregion
    }
}